/**
 * Name: LightsBorad
 * @author Zhongtian Jiang
 * @version 1.0
 * This is a Panel contains the board, some other buttons and labels
 */
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JOptionPane;
import java.awt.Dimension;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
 * @author Master
 * @version $Revision: 1.0 $
 */
public class LightsPanel extends JPanel{
	/**
	 * Field YIBAIWAN.
	 * (value is 1000000)
	 */
	private static final int YIBAIWAN = 1000000;
	
	/**
	 * Field ERSHI.
	 * (value is 20)
	 */
	private static final int ERSHI = 20;

	/**
	 * Field SHI.
	 * (value is 10)
	 */
	private static final int SHI = 10;

	/**
	 * Field Board.
	 */
	private final LightsBoard board;

	/**
	 * Field exit.
	 */
	/**
	 * Field wantahint.
	 */
	/**
	 * Field showstep.
	 */
	/**
	 * Field reset.
	 */
	private final JButton reset, showstep, wantahint, exit;

	/**
	 * Field STEP.
	 */
	private final JLabel step;
	
	/**
	 * Field toshowstep.
	 */
	public boolean toshowstep=false;

	/**
	 * Field M.
	 */
	/**
	 * Field N.
	 */
	private final int nNN, mMM;

	/**
     * constructor
     * @param n height of the board
     * @param m width of the board
	 */
	public LightsPanel(int n, int m) {
		nNN=n;
		mMM=m;
		wantahint=new JButton("Hint");
		wantahint.addActionListener(new ButtonListener());
		reset=new JButton("Reset");
		exit=new JButton("Leave the Temple");
		exit.addActionListener(new ExitListener());
		reset.addActionListener(new ButtonListener());
		showstep=new JButton("Show minimun step");
		showstep.addActionListener(new ButtonListener());
		step=new JLabel("Step Hidden");
		board=new LightsBoard(n, m, this);
		
		setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
		add(Box.createVerticalGlue());
		add(wantahint);
		add(Box.createRigidArea(new Dimension(0, SHI)));
		add(showstep);
		add(Box.createRigidArea(new Dimension(0, SHI)));
		add(step);
		add(Box.createRigidArea(new Dimension(0, SHI)));
		add(board);
		add(Box.createRigidArea(new Dimension(0, SHI)));
		add(reset);
		add(Box.createRigidArea(new Dimension(0, SHI)));
		add(exit);
		setBackground(Color.white);
	}

	/**
     * if any of the button is clicked or the board is changed,
     * this function is to recalculate the minimum step to win
     */
	public void reCalculate(){
		if (toshowstep){
			if(Math.min(nNN, mMM) < ERSHI && 
			  (nNN * mMM * (1 << (Math.min(nNN, mMM))) < YIBAIWAN)) {
				step.setText("Minimum Steps to Win: " + board.getMinimumStep());
			}
			else step.setText("Too large Board, cannot calculate :(");
			showstep.setText("Hide Minimum Steps");
		}else {
			step.setText("Minimum Steps Hidden");
			showstep.setText("Show minimun step");
		}
	}

	/**
	 * @author Master
	 */
	public class ButtonListener implements ActionListener{
		/**
		 * Method actionPerformed.
		 * @param e ActionEvent
		
		 * @see java.awt.event.ActionListener#actionPerformed(ActionEvent) */
		@Override
		public void actionPerformed(ActionEvent e) {
			if (e.getSource().equals(reset)){
				board.reset();
				reCalculate();
			}else if (e.getSource().equals(showstep)){
				toshowstep=!toshowstep;
				reCalculate();
			}else if (e.getSource().equals(wantahint)){
				if(Math.min(nNN, mMM) > ERSHI ||
				  (nNN * mMM * (1 << (Math.min(nNN, mMM))) > YIBAIWAN)) {
					JOptionPane.showMessageDialog(getParent(), "Too large Board!");
				}
				else board.toGetHint();
			}
		}

		/**
		 * Method toString.
		
		 * @return String */
		@Override
		public String toString() {
			return "ButtonListener []";
		}
		
	}

	/**
	 * @author Master
	 */
	public static class ExitListener implements ActionListener{
		/**
		 * Method toString.
		
		 * @return String */
		@Override
		public String toString() {
			return "ExitListener []";
		}

		/**
		 * Method actionPerformed.
		 * @param e ActionEvent
		
		 * @see java.awt.event.ActionListener#actionPerformed(ActionEvent) */
		@Override
		public void actionPerformed(ActionEvent e) {
			LightsMain.Frame.dispose();
		}
		
	}
}
